package sentinel;

import com.alibaba.cloud.sentinel.SentinelProperties;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.Ordered;
import org.springframework.core.PriorityOrdered;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.Objects;
import java.util.stream.Collectors;

@Configuration(proxyBeanMethods = false)
@PropertySource(value = "classpath:sentinel-auto.yml", factory = ConfigSourceFactory.class)
class SentinelAutoConfiguration {
    @Component
    static class SentinelPropertiesBeanPostProcessor implements PriorityOrdered, BeanPostProcessor {
        DiscoveryClient discoveryClient;
        SentinelProperties sentinelProperties;
        final static String SENTINEL_DASHBOARD = "sentinel-dashboard";

        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            if (bean instanceof SentinelProperties) {
                sentinelProperties = (SentinelProperties) bean;
                setDashboard();
            } else if (bean instanceof DiscoveryClient) {
                discoveryClient = (DiscoveryClient) bean;
                setDashboard();
            }
            return bean;
        }

        private void setDashboard() {
            if (Objects.isNull(discoveryClient) || Objects.isNull(sentinelProperties)) return;

            SentinelProperties.Transport transport = sentinelProperties.getTransport();
            if (!"sentinel-dashboard:8080".equals(transport.getDashboard())) return;

            String serverList = discoveryClient.getServices().stream().filter(s ->
                    s.contains(SENTINEL_DASHBOARD)
            ).flatMap(s -> discoveryClient.getInstances(s).stream()).map(instance ->
                    String.format("%s:%s", instance.getHost(), instance.getPort())
            ).collect(Collectors.joining(","));
            if (StringUtils.hasLength(serverList)) {
                transport.setDashboard(serverList);
            }
        }

        @Override
        public int getOrder() {
            return Ordered.HIGHEST_PRECEDENCE;
        }
    }
}